#pragma once
#include <iostream>
#include <string>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

class InetAdrr {
    void ToHost(const struct sockaddr_in& addr) {
        // inet_ntoa 函数不是线程安全的函数，推荐使用 inet_ntop 函数
        // _ip = inet_ntoa(addr.sin_addr);
        char ip_buff[32];

        // 该函数是网络序列转主机序列 :network to process
        inet_ntop(AF_INET, &addr.sin_addr, ip_buff, sizeof(ip_buff));
        // 若想要将主机序列转换成网络序列使用函数 :
        // inet_pton(AF_INET, _ip.c_str(), (void*)&addr.sin_addr.s_addr); 
        _ip = ip_buff;
        _port = ntohs(addr.sin_port);
    }
public:
    InetAdrr() {}

    InetAdrr(const struct sockaddr_in& addr) : _addr(addr)
    {
        ToHost(_addr);
    }

    InetAdrr& operator=(const struct sockaddr_in& addr) {
        _addr = addr;
        ToHost(_addr);
        return *this;
    }

    std::string Ip() const {
        return _ip;
    }

    bool operator==(const InetAdrr& addr) {
        return (_port == addr._port && _ip == addr._ip);
    }

    struct sockaddr_in Addr() const {
        return _addr;
    }

    std::string AddrString() const {
        return _ip + ":" + std::to_string(_port);
    }

    uint16_t Port() const {
        return _port;
    }

    ~InetAdrr() {}
private:
    uint16_t _port;
    std::string _ip;
    struct sockaddr_in _addr;
};